using System;
using System.Collections.Generic;
using System.Threading;


    /// <summary>
    /// 事件执行信息结构体
    /// 用于存储异步事件执行所需的信息
    /// </summary>
    internal struct GameEventInfo
    {
        public GameEventHandler eventHandler; // 事件处理委托
        public object[] args;                // 事件参数数组
    }

    /// <summary>
    /// 事件处理委托定义
    /// 外部事件函数的格式标准
    /// params object[] 表示可变参数数组
    /// </summary>
    public delegate void GameEventHandler(params object[] args);

    /// <summary>
    /// 游戏事件管理系统
    /// 提供事件的注册、移除、同步/异步触发等功能
    /// </summary>
    public class GameEvent :Singleton<GameEvent>
    {
        /// <summary>
        /// 异步事件执行列表
        /// 存储待处理的异步事件
        /// </summary>
        private List<GameEventInfo> mAsyncEventList;

        /// <summary>
        /// 事件字典
        /// key: 事件类型(string)
        /// value: 该类型的事件处理委托列表
        /// </summary>
        private Dictionary<string, List<GameEventHandler>> mEventDic;

        /// <summary>
        /// 一次性事件字典
        /// key: 事件类型(string)
        /// value: 只执行一次的事件处理委托
        /// </summary>
        private Dictionary<string, GameEventHandler> mUseOnceEventDic;

        /// <summary>
        /// 构造函数
        /// 初始化所有事件集合
        /// </summary>
        public GameEvent()
        {
            mAsyncEventList = new List<GameEventInfo>();
            mEventDic = new Dictionary<string, List<GameEventHandler>>();
            mUseOnceEventDic = new Dictionary<string, GameEventHandler>();
        }

        /// <summary>
        /// 添加事件监听
        /// </summary>
        /// <param name="type">事件类型</param>
        /// <param name="handler">事件处理委托</param>
        /// <param name="isUseOnce">是否只执行一次(默认为false)</param>
        public void AddEvent(string type, GameEventHandler handler, bool isUseOnce = false)
        {
            // 获取或创建该类型的事件处理器列表
            List<GameEventHandler> handlerList = mEventDic.ContainsKey(type) ? mEventDic[type] : null;
            if (handlerList == null)
            {
                mEventDic[type] = new List<GameEventHandler>();
            }

            // 防止重复添加相同的处理器
            if (mEventDic[type].Contains(handler))
                return;

            // 添加处理器到列表
            mEventDic[type].Add(handler);

            // 如果是一次性事件，添加到一次性字典
            if (isUseOnce && !mUseOnceEventDic.ContainsKey(type))
                mUseOnceEventDic.Add(type, handler);
        }

        /// <summary>
        /// 移除特定事件的特定监听器
        /// </summary>
        /// <param name="type">事件类型</param>
        /// <param name="handler">要移除的事件处理委托</param>
        public void RemoveEvent(string type, GameEventHandler handler)
        {
            // 从主事件字典中移除
            List<GameEventHandler> handlerList = mEventDic.ContainsKey(type) ? mEventDic[type] : null;
            if (handlerList != null && handlerList.Contains(handler))
            {
                handlerList.Remove(handler);
            }

            // 从一次性事件字典中移除
            if (mUseOnceEventDic.ContainsKey(type) && mUseOnceEventDic[type] == handler)
                mUseOnceEventDic.Remove(type);
        }

        /// <summary>
        /// 移除特定类型的所有事件监听
        /// </summary>
        /// <param name="type">要移除的事件类型</param>
        public void RemoveEvent(string type)
        {
            if (mEventDic.ContainsKey(type))
                mEventDic.Remove(type);

            if (mUseOnceEventDic.ContainsKey(type))
                mUseOnceEventDic.Remove(type);
        }

        /// <summary>
        /// 移除所有事件监听
        /// 清空所有事件集合
        /// </summary>
        public void RemoveEvent()
        {
            mEventDic.Clear();
            mUseOnceEventDic.Clear();
        }

        /// <summary>
        /// 同步触发事件
        /// 立即执行所有注册的处理器
        /// </summary>
        /// <param name="type">要触发的事件类型</param>
        /// <param name="args">事件参数</param>
        public void DispatchEvent(string type, params object[] args)
        {
            // 获取该类型的所有处理器
            List<GameEventHandler> handlerList = mEventDic.ContainsKey(type) ? mEventDic[type] : null;

            if (handlerList != null && HasEvent(type))
            {
                for (short i = 0; i < handlerList.Count; i++)
                {
                    // 执行处理器
                    handlerList[i](args);

                    // 如果是一次性事件，执行后移除
                    if (mUseOnceEventDic.ContainsKey(type) && mUseOnceEventDic[type] == handlerList[i])
                        RemoveEvent(type, handlerList[i]);
                }
            }
        }

        /// <summary>
        /// 异步触发事件
        /// 将事件加入队列，在UpdateEvent中处理
        /// </summary>
        /// <param name="type">事件类型</param>
        /// <param name="args">事件参数</param>
        public void DispatchAsyncEvent(string type, params object[] args)
        {
            List<GameEventHandler> handlerList = mEventDic.ContainsKey(type) ? mEventDic[type] : null;
            if (handlerList != null && HasEvent(type))
            {
                for (short i = 0; i < handlerList.Count; i++)
                {
                    // 将事件信息加入异步队列
                    mAsyncEventList.Add(new GameEventInfo()
                    {
                        args = args,
                        eventHandler = handlerList[i]
                    });

                    // 如果是一次性事件，执行后移除
                    if (mUseOnceEventDic.ContainsKey(type) && mUseOnceEventDic[type] == handlerList[i])
                        RemoveEvent(type, handlerList[i]);
                }
            }
        }


        /// <summary>
        /// 检查是否存在特定类型的事件监听
        /// </summary>
        /// <param name="type">要检查的事件类型</param>
        /// <returns>是否存在该类型的事件监听</returns>
        public bool HasEvent(string type)
        {
            return mEventDic.ContainsKey(type);
        }

        /// <summary>
        /// 事件更新循环
        /// 在主游戏循环中调用，处理所有异步事件
        /// </summary>
        public void UpdateEvent()
        {
            // 遍历处理所有异步事件
            for (short i = 0; i < mAsyncEventList.Count; i++)
            {
                GameEventInfo taskEvent = mAsyncEventList[i];
                mAsyncEventList.Remove(taskEvent);  // 从队列移除
                taskEvent.eventHandler(taskEvent.args);  // 执行处理器
            }
        }

        /// <summary>
        /// 释放资源
        /// 清空所有集合并释放引用
        /// </summary>
        public void Dispose()
        {
            mUseOnceEventDic.Clear();
            mEventDic.Clear();
            mAsyncEventList.Clear();
            mAsyncEventList = null;
            mEventDic = null;
            mUseOnceEventDic = null;
        }
    }
